package blog

import (
	"context"
	"strconv"
)

const AppName = "BlogController"

type BlogService interface {
	// 创建博客
	CreateBlog(context.Context, *CreateBlogRequest) (*Blog, error)
	// 查询文章列表, 列表查询, 没有必要查询文章的具体内容
	// 返回的是多个Blog，所以不能用*Blog
	QueryBlog(context.Context, *QueryBlogRequest) (*BlogSet, error)
	// 详情页, 尽量多的把关联的数据查询出来， content
	DescribeBlog(context.Context, *DescribeBlogRequest) (*Blog, error)
	// 修改文章状态
	UpdateBlogStatus(context.Context, *UpdateBlogStatusRequest) (*Blog, error)
	// 更新文章
	UpdateBlog(context.Context, *UpdateBlogRequest) (*Blog, error)
	// 删除文章
	DeleteBlog(context.Context, *DeleteBlogRequest) error
	// 文章审核, 审核通过的文章才能被看到
	AuditBlog(context.Context, *AuditBlogRequest) (*Blog, error)
}

type CreateBlogRequest struct {
	// 文章标题
	Title string `json:"title"`
	// 作者
	Author string `json:"author"`
	// 用户登录后, 我们通过Token知道是哪个用户
	CreateBy string `json:"create_by"`
	// 文章内容
	Content string `json:"content"`
	// 概要
	Summary string `json:"summary"`
	// 标签, 基于标签做分类, 语言:Golang, 分类:后端
	// 存入数据库的话，就要通过gorm转换
	Tags map[string]string `json:"tags" gorm:"serializer:json"`
}

func NewCreateBlogRequest() *CreateBlogRequest {
	return &CreateBlogRequest{
		Tags: map[string]string{},
	}
}

type QueryBlogRequest struct {
	// 一页的大小，也就是一页有多少行
	PageSize int `json:"page_size"`
	// 当前处于几页
	PageNumber int `json:"page_number"`
	/* 因为要根据blog状态来查询，所以要定义此属性；为什么用指针呢？
	因为要实现nil的查询条件，如果不用指针，只能表示0、1条件 */
	// nil 没有这个过滤条件,为默认条件，表示要查询所有的博客
	// 0   DRAFT 表示草稿状态
	// 1   PUBLISHED 表示已发布状态
	Status *Status `json:"status"`
	// 基于文章标题的关键字搜索
	Keywords string `json:"keywords"`
	// 查询属于哪些用户的博客
	Usernames []string `json:"Usernames"`
}

func NewQueryBlogRequest() *QueryBlogRequest {
	return &QueryBlogRequest{
		PageSize:   10,
		PageNumber: 1,
		Usernames:  []string{},
	}
}

func (q *QueryBlogRequest) Offset() int {
	return q.PageSize * (q.PageNumber - 1)
}

func (q *QueryBlogRequest) Setstatus(s Status) {
	var a = s
	q.Status = &a
}

func (q *QueryBlogRequest) ParsePageSize(s string) {
	i, err := strconv.Atoi(s)
	if err == nil {
		q.PageSize = i
	}
}
func (q *QueryBlogRequest) ParsePageNumber(s string) {
	i, err := strconv.Atoi(s)
	if err == nil {
		q.PageNumber = i
	}
}
func (q *QueryBlogRequest) SetStatus(s Status) {
	var a = s
	q.Status = &a
}

type DescribeBlogRequest struct {
	BlogId string `json:"blog_id"`
}

func NewDescribeBlogRequest(id string) *DescribeBlogRequest {
	return &DescribeBlogRequest{
		BlogId: id,
	}
}

type UpdateBlogStatusRequest struct {
}

type UpdateBlogRequest struct {
	BlogId     string     `json:"blog_id"`
	UpdateMode UpdateMode `json:"update_mode"`
	*CreateBlogRequest
}

func NewPutUpdateBlogRequest(id string) *UpdateBlogRequest {
	return &UpdateBlogRequest{
		BlogId:            id,
		UpdateMode:        UPDATE_MODE_PUT,
		CreateBlogRequest: NewCreateBlogRequest(),
	}
}
func NewPatchUpdateBlogRequest(id string) *UpdateBlogRequest {
	return &UpdateBlogRequest{
		BlogId:            id,
		UpdateMode:        UPDATE_MODE_PATCH,
		CreateBlogRequest: NewCreateBlogRequest(),
	}
}

type DeleteBlogRequest struct {
	BlogId string `json:"blog_id"`
}

func NewDeleteBlogRequest(id string) *DeleteBlogRequest {
	return &DeleteBlogRequest{
		BlogId: id,
	}
}

type AuditBlogRequest struct {
	BlogId      string `json:"blog_id"`
	IsAuditPass bool   `json:"is_audit_pass"`
}

func NewAuditBlogRequest(id string) *AuditBlogRequest {
	return &AuditBlogRequest{
		BlogId: id,
	}
}
